package operatemodel

import (
	"errors"
	"server/global"
	"server/model"
	entry "server/model/entrance"
	"strconv"
	"time"

	"github.com/go-redis/redis/v8"
	"gorm.io/gorm"
)

//Note :所有存储在redis的value数据都是string

//可以尝试redis自带的过期策略
//获取User数量,一个小时更新一次,num=-1表示获取失败
func GetuserNum() (Number int) {
	var flag = 0
Start:
	//拿取数据
	i, err := model.Redis.HMGet(model.Ctx, "numberofuser", "expiredtime", "number").Result()
	//空值情况 新存储
	if err == redis.Nil || i[0] == nil || i[1] == nil {
		usernum := getusernum()
		if usernum != -1 {
			// Flag:更新时间
			savetime := time.Now().Add(time.Hour).Unix()
			model.Redis.HSet(model.Ctx, "numberofuser", "expiredtime", savetime, "number", usernum)
		}
		//防止爆栈
		if flag++; flag > 50 {
			Number = -1
			return
		}
		goto Start
	} else if err != nil {
		//数据库出错
		Number = -1
		return
	}
	//时间推断
	i2, _ := strconv.Atoi(i[0].(string))
	if time.Now().Unix() > int64(i2) {
		usernum := getusernum()
		if usernum != -1 {
			// Flag:更新时间
			savetime := time.Now().Add(time.Hour).Unix()
			model.Redis.HSet(model.Ctx, "numberofuser", "expiredtime", savetime, "number", usernum)
		}
		//防止爆栈
		if flag++; flag > 50 {
			Number = -1
			return
		}
		//goto 不能跳转到子级标签里面的语句(子级私有)
		goto Start
	}
	i3, _ := strconv.Atoi(i[1].(string))
	Number = i3
	return
}
func getusernum() (Number int) {
	//数据存储在redis里面
	var uu []model.User
	d := model.DB.Find(&uu)
	if d.RowsAffected == 0 || d.Error != nil {
		Number = -1
		return
	}
	Number = len(uu)
	return
}

func Loginorsign(data *entry.Comment) (code int) {
	var user = model.User{
		Username: data.Username,
		Email:    data.Email,
		Avatar:   data.Imgurl,
	}
Start:
	//First只能查主键,其他不能查,不是mongodb
	d := model.DB.Where("username=? and email= ?", data.Username, data.Email).First(&user) //Row找不到也算在Error里面
	if d.RowsAffected == 0 { //找不到情况--就需要注册一个新用户了
		d = model.DB.Create(&user)
		if d.RowsAffected == 0 || d.Error != nil {
			code = global.EMAIL_REPEAT
			return
		}
		goto Start
	} else if d.Error != nil {
		code = global.FAIL
		return
	}
	code = global.SUCCESS
	return
}

func Getalluser() (code int, data []model.User) {
	d := model.DB.Find(&data)
	if d.RowsAffected == 0 {
		code = global.FAIL
		return
	} else if d.Error != nil {
		code = global.FAIL
		return
	}
	code = global.SUCCESS
	return
}

func Deleteuser(id int) (code int) {
	d := model.DB.Delete(&model.User{}, id)
	if errors.Is(d.Error, gorm.ErrRecordNotFound) {
		code = global.FAIL
		return
	} else if d.Error != nil {
		code = global.FAIL
		return
	}
	code = global.SUCCESS
	return
}
